package com.android.corestat.utils;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.os.Build;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;

/**
 * 类说明：
 * 
 * @author Baker.li
 * @date 2014年11月13日
 * @version 1.0
 */

public class IMEIUtils {
	private static final String TAG = "IMEIUtils";

	public static Map<String, String> getIMEIInfo(Context ctx) {
		if (ctx == null) {
			return null;
		}
		Map<String, String> map = null;
		do {
			map = getIMEIMTKDualSim(ctx);
			if (map != null && map.size() != 0) {
				break;
			}

			map = getIMEISpreadDualSim(ctx);
			if (map != null && map.size() != 0) {
				break;
			}

			map = getIMEIYulongDualSim();
			if (map != null && map.size() != 0) {
				break;
			}

			map = getIMEIQualcommDualSim(ctx);
			if (map != null && map.size() != 0) {
				break;
			}
			map = getIMEISamsungDualSim(ctx);
			if (map != null && map.size() != 0) {
				break;
			}
			map = getIMEILenovoDualSim(ctx);
			if (map != null && map.size() != 0) {
				break;
			}
			
			map = getIMEIS858tDualSim(ctx);
			if(map != null && map.size() != 0) {
				break;
			}

		} while (false);
		return map;
	}

	private static String convertPhoneType(int type) {
		if (type == TelephonyManager.PHONE_TYPE_CDMA) {
			return "meid";
		} else {
			return "imei";
		}
	}

	private static Map<String, String> getIMEIMTKDualSim(Context ctx) {
		if (ctx == null) {
			return null;
		}
		try {
			TelephonyManager tm = (TelephonyManager) ctx
					.getSystemService(Context.TELEPHONY_SERVICE);
			Class.forName("com.android.internal.telephony.Phone");
			Method ms[] = TelephonyManager.class.getDeclaredMethods();
			Log.e(TAG, ms.length + "");
			Method typeMethod = TelephonyManager.class.getDeclaredMethod("getPhoneTypeGemini",
					Integer.TYPE);

			Method idMethod = TelephonyManager.class.getDeclaredMethod("getDeviceIdGemini",
					Integer.TYPE);
			Map<String, String> map = new HashMap<String, String>();
			try {
				int type1 = (Integer) typeMethod.invoke(tm, 0);
				String id1 = (String) idMethod.invoke(tm, 0);
				if (!TextUtils.isEmpty(id1)) {
					map.put(convertPhoneType(type1) + "_1", id1);
				}
			} catch (Exception e) {
				Log.w(TAG, "mtk1 failed");
			}

			try {
				int type2 = (Integer) typeMethod.invoke(tm, 1);
				String id2 = (String) idMethod.invoke(tm, 1);
				if (!TextUtils.isEmpty(id2)) {
					map.put(convertPhoneType(type2) + "_2", id2);
				}
			} catch (Exception e) {
				Log.w(TAG, "mtk2 failed");
			}
			return map;
		} catch (ClassNotFoundException e) {
			Log.d(TAG, "mtk failed");
		} catch (NoSuchMethodException e) {
			Log.d(TAG, "mtk failed");
		}
		return null;
	}

	private static Map<String, String> getIMEIYulongDualSim() {
		try {
			Class<?> cptmCls = Class.forName("com.yulong.android.telephony.CPTelephonyManager");
			/** phoneId, devType */
			// MEID: 1 1(CDMA) 99000522345739
			// IMEI1:1 2(GSM) 863508027790581
			// IMEI2:2 1(GSM) 863508027807468
			Method getDefault = cptmCls.getMethod("getDefault");
			Object instance;
			try {
				instance = getDefault.invoke(null);
			} catch (Exception e1) {
				instance = null;
				return null;
			}

			Method method = cptmCls.getMethod("getYLDeviceId", Integer.TYPE, Integer.TYPE);
			Method typeMethod = cptmCls.getMethod("getPhoneTypeByPhoneId", Integer.TYPE);
			Map<String, String> map = new HashMap<String, String>();
			try {
				int type1 = (Integer) typeMethod.invoke(instance, 1);
				if (type1 == TelephonyManager.PHONE_TYPE_CDMA) {
					String IMEI_1 = (String) method.invoke(instance, 1, 2);
					if (!TextUtils.isEmpty(IMEI_1)) {
						map.put("imei_1", IMEI_1);
					}
					String MEID_1 = (String) method.invoke(instance, 1, 1);
					if (!TextUtils.isEmpty(MEID_1)) {
						map.put("meid_1", MEID_1);
					}
				} else {
					String IMEI_1 = (String) method.invoke(instance, 1, 1);
					if (TextUtils.isEmpty(IMEI_1)) {
						IMEI_1 = (String) method.invoke(instance, 1, 2);
					}
					if (!TextUtils.isEmpty(IMEI_1)) {
						map.put("imei_1", IMEI_1);
					}
				}
				int type2 = (Integer) typeMethod.invoke(instance, 2);
				if (type2 == TelephonyManager.PHONE_TYPE_CDMA) {
					String MEID_2 = (String) method.invoke(instance, 2, 1);
					if (!TextUtils.isEmpty(MEID_2)) {
						map.put("meid_2", MEID_2);
					}
					String IMEI_2 = (String) method.invoke(instance, 2, 2);
					if (!TextUtils.isEmpty(IMEI_2)) {
						map.put("imei_2", IMEI_2);
					}
				} else {
					String IMEI_2 = (String) method.invoke(instance, 2, 1);
					if (TextUtils.isEmpty(IMEI_2)) {
						IMEI_2 = (String) method.invoke(instance, 2, 2);
					}
					if (!TextUtils.isEmpty(IMEI_2)) {
						map.put("imei_2", IMEI_2);
					}
				}
				return map;
			} catch (Exception e) {
				e.printStackTrace();
			}

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		return null;
	}

	private static Map<String, String> getIMEISamsungDualSim(Context ctx) {
		if (Build.BRAND == null || !Build.BRAND.toLowerCase().contains("samsung")) {
			return null;
		}
		ctx = ctx.getApplicationContext();
		TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
		// int phoneType = tm.getPhoneType();
		Map<String, String> map = new HashMap<String, String>();
		// String MODEL = TextUtils.isEmpty(Build.MODEL) ? "unknown" :
		// Build.MODEL;
		// if ((MODEL.contains("gt-i9502")) || (MODEL.contains("sch-i869via"))
		// || (MODEL.contains("sm-n9002"))) {
		// try {
		// Method getFirstMethod = TelephonyManager.class.getMethod("getFirst");
		// Method getSecondMethod =
		// TelephonyManager.class.getMethod("getSecondary");
		// TelephonyManager tm1 = (TelephonyManager) getFirstMethod.invoke(tm);
		// TelephonyManager tm2 = (TelephonyManager) getSecondMethod.invoke(tm);
		// if (!TextUtils.isEmpty(tm1.getDeviceId())) {
		// map.put(convertPhoneType(tm1.getPhoneType()) + "_1",
		// tm1.getDeviceId());
		// }
		// if (!TextUtils.isEmpty(tm2.getDeviceId())) {
		// map.put(convertPhoneType(tm2.getPhoneType()) + "_2",
		// tm2.getDeviceId());
		// }
		// if (map.size() != 0) {
		// return map;
		// }
		// } catch (Exception e) {
		// Log.w(TAG, "faied to get first and second");
		// }
		// }

		map.put(convertPhoneType(tm.getPhoneType()) + "_1", tm.getDeviceId());
		TelephonyManager tm2 = (TelephonyManager) ctx.getSystemService("phone2");
		if (tm2 != null) {
			if (!TextUtils.isEmpty(tm2.getDeviceId())) {
				map.put(convertPhoneType(tm2.getPhoneType()) + "_2", tm2.getDeviceId());
			}
		}
		return map;
	}

	private static Map<String, String> getIMEIQualcommDualSim(Context ctx) {
		try {
			Class<?> cx = Class.forName("android.telephony.MSimTelephonyManager");
			Object obj = ctx.getSystemService("phone_msim");
			if (obj == null) {
				return null;
			}
			Method idMethod = cx.getMethod("getDeviceId", int.class);
			Method typeMethod = cx.getMethod("getPhoneType", int.class);
			Map<String, String> map = new HashMap<String, String>();
			try {
				int type1 = (Integer) typeMethod.invoke(obj, 0);
				String id1 = (String) idMethod.invoke(obj, 0);
				if (!TextUtils.isEmpty(id1)) {
					map.put(convertPhoneType(type1) + "_1", id1);
				}
			} catch (Exception e) {
				Log.w(TAG, "qualcomm1 failed");
			}
			try {
				int type2 = (Integer) typeMethod.invoke(obj, 1);
				String id2 = (String) idMethod.invoke(obj, 1);
				if (!TextUtils.isEmpty(id2)) {
					map.put(convertPhoneType(type2) + "_2", id2);
				}
			} catch (Exception e) {
				Log.w(TAG, "qualcomm2 failed");
			}

			return map;
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}


	private static Map<String, String> getIMEILenovoDualSim(Context ctx) {
		if (ctx == null) {
			return null;
		}
		try {
			Class<?> cx = Class.forName("android.telephony.MSimTelephonyManager");
			Object obj = ctx.getSystemService("phone_msim");
			if (obj == null) {
				return null;
			}
			
			Method idMethod = cx.getMethod("getDeviceId", int.class);
			Method typeMethod = cx.getMethod("getCurrentPhoneType", int.class);
			
			Map<String, String> map = new HashMap<String, String>();
			try{
				int type1 = (Integer) typeMethod.invoke(obj, 0);
				String id1 = (String) idMethod.invoke(obj, 0);
				if(!TextUtils.isEmpty(id1)) {
					map.put(convertPhoneType(type1) + "_1", id1);
				}
			} catch(Exception e) {
				e.printStackTrace();
				Log.w(TAG, "Lenovo1 failed");
			}
			
			try{
				int type2 = (Integer) typeMethod.invoke(obj, 1);
				String id2 = (String) idMethod.invoke(obj, 1);
				if(!TextUtils.isEmpty(id2)) {
					map.put(convertPhoneType(type2) + "_2", id2);
				}
			} catch(Exception e) {
				e.printStackTrace();
				Log.w(TAG, "Lenovo2 failed");
			}
			return map;
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	private static Map<String, String> getIMEISpreadDualSim(Context ctx) {
		try {
			Class<?> c = Class.forName("com.android.internal.telephony.PhoneFactory");
			Method m = c.getMethod("getServiceName", String.class, int.class);
			String spreadTmService = (String) m.invoke(c, Context.TELEPHONY_SERVICE, 1);

			TelephonyManager tm = (TelephonyManager) ctx
					.getSystemService(Context.TELEPHONY_SERVICE);

			TelephonyManager tm1 = (TelephonyManager) ctx.getSystemService(spreadTmService);
			String id1 = tm.getDeviceId();
			String id2 = tm1.getDeviceId();
			Map<String, String> map = new HashMap<String, String>();
			if (!TextUtils.isEmpty(id1)) {
				map.put(convertPhoneType(tm.getPhoneType()) + "_1", id1);
			}
			if (!TextUtils.isEmpty(id2)) {
				map.put(convertPhoneType(tm1.getPhoneType()) + "_2", id2);
			}
			return map;
		} catch (Exception e) {
			Log.w(TAG, "spread failed");
		}
		return null;
	}
	
	private static Map<String, String> getIMEIS858tDualSim(Context ctx) {
		if (ctx == null) {
			return null;
		}
		try {
			Class<?> clx = Class.forName("com.mediatek.telephony.TelephonyManagerEx");
			Method getDefault = clx.getMethod("getDefault");
			Object instance;
			try {
				instance = getDefault.invoke(null);
			} catch (Exception e1) {
				instance = null;
				return null;
			}
			
			Method idMethod = clx.getMethod("getDeviceId", int.class);
			Method typeMethod = clx.getMethod("getPhoneType", int.class);
			Map<String, String> map = new HashMap<String, String>();
			try {
				int type1 = (Integer) typeMethod.invoke(instance, 0);
				String id1 = (String) idMethod.invoke(instance, 0);
				if (!TextUtils.isEmpty(id1)) {
					map.put(convertPhoneType(type1) + "_1", id1);
				}
			} catch (Exception e) {
				Log.w(TAG, "S858t1 imei2 failed");
			}

			try {
				int type2 = (Integer) typeMethod.invoke(instance, 1);
				String id2 = (String) idMethod.invoke(instance, 1);
				if (!TextUtils.isEmpty(id2)) {
					map.put(convertPhoneType(type2) + "_2", id2);
				}
			} catch (Exception e) {
				Log.w(TAG, "S858t imei2 failed");
			}
			return map;
		} catch(Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
